

'use strict'

const {deep_copy, contain_no_seq} = require('./utils')
const KeyWordCannotOverWrite = require('./exception/KeyWordCannotOverWrite')

let g_rule = []
let g_keyword = ['angularjs', 'async']
let g_handler = {}

class ModelDecorator{
    constructor(){

        /**
         * 用于装饰模型
        */
        
        this.__rule = deep_copy(g_rule)
        this.__keyword = deep_copy(g_keyword)
        this.__handler = deep_copy(g_handler)
    }
    addRule(fn, need){
        this.__rule.push({need : need || [], fn : fn})
        return this
    }
    addKeyWord(keyword){
        if(keyword instanceof Array){
            this.__keyword = this.__keyword.concat(keyword)
        }else{
            this.__keyword.push(keyword)
        }
        return this
    }
    addHandler(config){
        for(let [k, v] of Object.entries(config)){
            this.__handler[k] = v
        }
        return this
    }
    execute(){
        this.__rule.forEach(elem=>{
            contain_no_seq(this.__keyword, elem.need) && elem.fn(this.__handler)
        })
        return this
    }
    static addRule(fn, need){
        g_rule.push({need : need || [], fn : fn})
        return ModelDecorator
    }
    static addKeyWord(keyword){
        g_keyword.push(keyword)
        return ModelDecorator
    }
    static addHandler(config){
        for(let [k, v] of Object.entries(config)){
            g_handler[k] = v
        }
        return ModelDecorator
    }
}

ModelDecorator.addHandler({
    impl(clazz, method_name, method){
        if(method_name in clazz.prototype){
            throw new KeyWordCannotOverWrite(clazz, method_name)
        }
        clazz.prototype[method_name] = method
    }
})

module.exports = ModelDecorator